﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace PS2FastLoader
{
    public partial class Form1 : Form
    {
        private BackgroundWorker bgw;
        private String ps2Directory;
        private static int readAheadSize = 4 * 1024 * 1024; // default to 8 MB
        public Form1()
        {
            InitializeComponent();
            InitializeBackgroundWorker();
        }
        private void InitializeBackgroundWorker()
        {
            bgw = new BackgroundWorker();
            bgw.WorkerReportsProgress = true;
            bgw.WorkerSupportsCancellation = true;
            bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
            bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
            bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_Completed);
        }
        private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBarLoading.Value = e.ProgressPercentage;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ps2Directory = DetermineDirectiory();
            if (ps2Directory != null)
            {
                labelMainLabel.Text = String.Format("Loading from {0}", ps2Directory);
                bgw.RunWorkerAsync();
            }
            else
            {
                MessageBox.Show("PlanetSide 2 not found, please copy this file to the directory which contains PlanetSide2.exe and re-run the program", "PlanetSide.exe not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        private static String DetermineDirectiory()
        {
            String directory = null;
            List<String> candidates = new List<string>()
            {
                @"Users\Public\Sony Online Entertainment\Installed Games\PlanetSide 2",
                @"Program Files (x86)\Steam\steamapps\common\PlanetSide 2",
                @"Program Files\Steam\steamapps\common\PlanetSide 2"
            };
            String testFname = "PlanetSide2.exe";
            DriveInfo[] driveInfos = DriveInfo.GetDrives();
            foreach (DriveInfo driveInfo in driveInfos)
            {
                DirectoryInfo rootDirectoryInfo = driveInfo.RootDirectory;
                String rootName = rootDirectoryInfo.FullName;
                foreach (String candidate in candidates)
                {
                    String thisFname = String.Format("{0}{1}\\{2}", rootName, candidate, testFname);
                    if (File.Exists(thisFname))
                    {
                        directory = rootName + candidate;
                    }
                }
            }
            if (directory == null)
            {
                directory = Directory.GetCurrentDirectory();
                if (!File.Exists(directory + "\\PlanetSide2.exe"))
                {
                    directory = null;
                }
            }
            return directory;
        }

        private void bgw_Completed(object sender, AsyncCompletedEventArgs e)
        {
            System.Diagnostics.Process.Start(ps2Directory + "\\LaunchPad.exe");
            this.Close();
        }

        private void bgw_DoWork(object sender, EventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            byte[] buffer = new byte[readAheadSize];
            string[] files = Directory.GetFiles(ps2Directory + @"\Resources\Assets", "*.pack", SearchOption.TopDirectoryOnly);
            
            if (files.Length <= 0)
            {
                throw new Exception(String.Format("No files found in `{0}`!", ps2Directory));
            }

            int doneFiles = 0;

            foreach (string fname in files)
            {
                int readPoint = 0;
                int n = 0;
                using (FileStream fs = File.Open(String.Format(@"{0}", fname), FileMode.Open, FileAccess.Read))
                {
                    do
                    {
                        n = fs.Read(buffer, 0, readAheadSize);
                        readPoint += n;
                    } while (n > 0);
                }
                worker.ReportProgress(++doneFiles);
            }
        }
    }
}
